import SwiftUI

struct ScenarioListView: View {
    @EnvironmentObject var sensor: SensorRecorder
    @AppStorage("userName") private var userName: String = ""
    
    @State private var selectedScenario: Scenario?
    @State private var pendingDuration: Double = 60
    @State private var activeScenario: Scenario?
    
    @State private var showCountdown: Bool = false
    @State private var countdownValue: Int = 3
    
    @State private var isRecording: Bool = false
    @State private var recordingProgress: Double = 0
    @State private var recordingStartDate: Date?
    @State private var recordingTotalSec: Double = 60
    @State private var timer: Timer?
    
    @State private var showNoteSheet: Bool = false
    @State private var noteText: String = ""
    @State private var lastSession: Session?
    @State private var sessions: [Session] = []
    @State private var isUploading: Bool = false
    @State private var uploadError: String?
    @State private var uploadSuccess: Bool = false
    
    private let columns = [
        GridItem(.flexible(), spacing: 16),
        GridItem(.flexible(), spacing: 16)
    ]
    
    var body: some View {
        NavigationStack {
            ZStack {
                // 背景渐变
                LinearGradient(colors: [.black.opacity(0.95), .blue.opacity(0.5)], startPoint: .topLeading, endPoint: .bottomTrailing)
                    .ignoresSafeArea()
                
                ScrollView {
                    VStack(alignment: .leading, spacing: 20) {
                        header
                        
                        // 按类别分组展示场景
                        ForEach(Scenario.groupedByCategory(), id: \.category) { group in
                            VStack(alignment: .leading, spacing: 12) {
                                // 类别标题
                                HStack(spacing: 8) {
                                    Image(systemName: categoryIcon(for: group.category))
                                        .font(.system(size: 16, weight: .semibold))
                                        .foregroundColor(.white.opacity(0.9))
                                    Text(group.category.rawValue)
                                        .font(.system(.subheadline, design: .rounded).weight(.bold))
                                        .foregroundColor(.white.opacity(0.9))
                                }
                                .padding(.horizontal, 4)
                                
                                // 该类别下的场景卡片
                                LazyVGrid(columns: columns, spacing: 12) {
                                    ForEach(group.scenarios) { scenario in
                                        ScenarioCard(scenario: scenario)
                                            .onTapGesture {
                                                selectedScenario = scenario
                                                pendingDuration = scenario.defaultDurationSec
                                            }
                                    }
                                }
                            }
                        }
                    }
                    .padding(20)
                }
            }
            .navigationTitle("采集场景")
            .navigationBarTitleDisplayMode(.inline)
            .sheet(item: $selectedScenario) { scenario in
                ScenarioConfirmSheet(
                    scenario: scenario,
                    duration: $pendingDuration,
                    onCancel: { selectedScenario = nil },
                    onConfirm: { startCountdown(for: scenario, seconds: pendingDuration) }
                )
                .presentationDetents([.height(360), .medium])
                .presentationCornerRadius(20)
            }
            .overlay(countdownOverlay)
            .overlay(recordingHUD)
            .sheet(isPresented: $showNoteSheet) {
                NoteInputSheet(noteText: $noteText) { note in
                    if var session = lastSession {
                        session.note = note
                        sessions.append(session)
                    }
                    // 关闭备注输入框
                    showNoteSheet = false
                    // 开始上传流程
                    Task {
                        await uploadDataToServer(note: note)
                    }
                    noteText = ""
                }
                .presentationDetents([.height(260), .medium])
                .presentationCornerRadius(20)
            }
            .overlay {
                if isUploading {
                    UploadingOverlay()
                }
            }
            .alert("上传失败", isPresented: .constant(uploadError != nil)) {
                Button("确定") { 
                    uploadError = nil
                    lastSession = nil
                    activeScenario = nil
                }
            } message: {
                Text(uploadError ?? "")
            }
            .alert("上传成功", isPresented: $uploadSuccess) {
                Button("确定") {
                    uploadSuccess = false
                    lastSession = nil
                    activeScenario = nil
                }
            } message: {
                Text("数据已成功保存到服务器")
            }
        }
        .preferredColorScheme(.dark)
    }
    
    private var header: some View {
        VStack(alignment: .leading, spacing: 6) {
            HStack(spacing: 10) {
                Image(systemName: "record.circle.fill")
                    .foregroundStyle(.red, .white)
                    .font(.system(size: 22))
                Text("选择一个场景开始采集")
                    .font(.system(.title3, design: .rounded).weight(.semibold))
            }
            Text("将以 50Hz 采集原始加速度计/陀螺仪与姿态补偿后的线性加速度，结束后自动导出 CSV。")
                .font(.footnote)
                .foregroundColor(.white.opacity(0.7))
        }
    }
    
    // MARK: - Countdown
    private var countdownOverlay: some View {
        Group {
            if showCountdown {
                ZStack {
                    Color.black.opacity(0.6).ignoresSafeArea()
                    VStack(spacing: 20) {
                        Text("准备开始")
                            .font(.system(.title2, design: .rounded).weight(.medium))
                            .foregroundColor(.white.opacity(0.9))
                        Text("\(countdownValue)")
                            .font(.system(size: 80, weight: .heavy, design: .rounded))
                            .foregroundStyle(LinearGradient(colors: [.blue, .cyan], startPoint: .topLeading, endPoint: .bottomTrailing))
                            .shadow(color: .blue.opacity(0.5), radius: 10, x: 0, y: 4)
                    }
                }
                .transition(.opacity)
            }
        }
        .animation(.easeInOut, value: showCountdown)
    }
    
    // MARK: - Recording HUD
    private var recordingHUD: some View {
        Group {
            if isRecording {
                ZStack {
                    Color.black.opacity(0.45).ignoresSafeArea()
                    VStack(spacing: 20) {
                        // 进度圆环和倒计时
                        ZStack {
                            Circle()
                                .stroke(lineWidth: 10)
                                .foregroundColor(.white.opacity(0.08))
                                .frame(width: 180, height: 180)
                            Circle()
                                .trim(from: 0, to: recordingProgress)
                                .stroke(AngularGradient(colors: [.red, .orange, .yellow, .green, .cyan, .blue, .purple, .red], center: .center), style: StrokeStyle(lineWidth: 10, lineCap: .round))
                                .rotationEffect(.degrees(-90))
                                .frame(width: 180, height: 180)
                                .animation(.easeInOut(duration: 0.2), value: recordingProgress)
                            VStack(spacing: 6) {
                                Image(systemName: "waveform.path.ecg")
                                    .font(.system(size: 24, weight: .bold))
                                    .foregroundColor(.white)
                                Text(timeRemainingString)
                                    .font(.system(.title3, design: .rounded).weight(.semibold))
                                    .foregroundColor(.white)
                                Text("\(sensor.sampleCount) 样本")
                                    .font(.caption)
                                    .foregroundColor(.white.opacity(0.7))
                            }
                        }
                        
                        // 实时传感器数据
                        VStack(spacing: 12) {
                            // 加速度计数据
                            SensorDataCard(
                                title: "加速度计",
                                icon: "arrow.up.and.down.and.arrow.left.and.right",
                                color: .cyan,
                                xValue: sensor.currentAccX,
                                yValue: sensor.currentAccY,
                                zValue: sensor.currentAccZ,
                                unit: "g"
                            )
                            
                            // 陀螺仪数据
                            SensorDataCard(
                                title: "陀螺仪",
                                icon: "gyroscope",
                                color: .orange,
                                xValue: sensor.currentGyroX,
                                yValue: sensor.currentGyroY,
                                zValue: sensor.currentGyroZ,
                                unit: "rad/s"
                            )
                        }
                        
                        HStack(spacing: 16) {
                            Button(role: .destructive) {
                                finishRecording(earlyStop: true)
                            } label: {
                                Label("提前结束", systemImage: "stop.circle.fill")
                                    .font(.system(.headline, design: .rounded))
                                    .padding(.horizontal, 18).padding(.vertical, 10)
                                    .background(.ultraThinMaterial)
                                    .cornerRadius(12)
                            }
                        }
                    }
                    .padding(24)
                    .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 24, style: .continuous))
                    .shadow(color: .black.opacity(0.35), radius: 30, x: 0, y: 20)
                    .padding(24)
                }
                .transition(.opacity)
            }
        }
        .animation(.easeInOut, value: isRecording)
    }
    
    private var timeRemainingString: String {
        guard let start = recordingStartDate else { return "--:--" }
        let elapsed = Date().timeIntervalSince(start)
        let remaining = max(0, recordingTotalSec - elapsed)
        let m = Int(remaining) / 60
        let s = Int(remaining) % 60
        return String(format: "%02d:%02d", m, s)
    }
    
    // MARK: - Flow
    private func startCountdown(for scenario: Scenario, seconds: Double) {
        selectedScenario = nil
        activeScenario = scenario
        countdownValue = 3
        showCountdown = true
        
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { t in
            countdownValue -= 1
            if countdownValue <= 0 {
                t.invalidate()
                showCountdown = false
                beginRecording(scenario: scenario, seconds: seconds)
            }
        }
    }
    
    private func beginRecording(scenario: Scenario, seconds: Double) {
        activeScenario = scenario
        recordingTotalSec = seconds
        recordingStartDate = Date()
        recordingProgress = 0
        isRecording = true
        
        // 开始 50Hz 采集
        sensor.start(rateHz: 50)
        
        timer?.invalidate()
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { t in
            guard let start = recordingStartDate else { return }
            let elapsed = Date().timeIntervalSince(start)
            recordingProgress = min(1.0, elapsed / recordingTotalSec)
            if elapsed >= recordingTotalSec {
                t.invalidate()
                finishRecording(earlyStop: false, scenario: scenario, actualDuration: elapsed)
            }
        }
    }
    
    private func finishRecording(earlyStop: Bool, scenario: Scenario? = nil, actualDuration: Double? = nil) {
        timer?.invalidate(); timer = nil
        sensor.stop()
        isRecording = false
        
        // 生成会话并请求备注
        let usedScenario = scenario ?? activeScenario ?? selectedScenario
        if let scenario = usedScenario, let start = recordingStartDate {
            let end = Date()
            let duration = actualDuration ?? end.timeIntervalSince(start)
            let session = Session(scenario: scenario, startDate: start, endDate: end, durationSec: duration, note: nil)
            lastSession = session
            showNoteSheet = true
        } else {
            // 若缺少上下文，也给出一个兜底的会话
            let scen = activeScenario ?? selectedScenario ?? Scenario.all.first!
            let now = Date()
            let session = Session(scenario: scen, startDate: now.addingTimeInterval(-1), endDate: now, durationSec: 1, note: nil)
            lastSession = session
            showNoteSheet = true
            activeScenario = nil
        }
    }
    
    // MARK: - Upload to Server
    private func uploadDataToServer(note: String) async {
        guard let session = lastSession, let scenario = activeScenario else {
            await MainActor.run {
                uploadError = "缺少会话信息"
            }
            return
        }
        
        await MainActor.run {
            isUploading = true
        }
        
        do {
            // 1. 导出 CSV 文件
            let urls = try sensor.exportCSVs(userName: userName, note: note)
            guard urls.count == 2 else {
                throw NSError(domain: "", code: -1, userInfo: [NSLocalizedDescriptionKey: "CSV 文件生成失败"])
            }
            let rawURL = urls[0]
            let linURL = urls[1]
            
            // 2. 生成 OSS 对象键（文件路径）
            let timestamp = Int(Date().timeIntervalSince1970)
            let rawObjectKey = "chew_data/\(userName)/\(timestamp)_raw.csv"
            let linObjectKey = "chew_data/\(userName)/\(timestamp)_lin.csv"
            
            // 3. 上传到阿里云 OSS
            let rawOSSUrl = try await OSSUploadService.shared.uploadFile(fileURL: rawURL, objectKey: rawObjectKey)
            let linOSSUrl = try await OSSUploadService.shared.uploadFile(fileURL: linURL, objectKey: linObjectKey)
            
            // 4. 调用后端接口保存数据
            try await ChewDataService.shared.saveChewData(
                scenario: scenario.title,
                note: note.isEmpty ? "未备注" : note,
                userName: userName,
                duration: session.durationSec,
                rawCsvUrl: rawOSSUrl,
                linCsvUrl: linOSSUrl
            )
            
            // 5. 成功
            await MainActor.run {
                isUploading = false
                uploadSuccess = true
            }
            
        } catch {
            await MainActor.run {
                isUploading = false
                uploadError = error.localizedDescription
            }
        }
    }
    
    // MARK: - Helper
    private func categoryIcon(for category: ScenarioCategory) -> String {
        switch category {
        case .sittingChewing:
            return "person.crop.circle.fill"
        case .sittingNonChewing:
            return "person.fill"
        case .walkingOnly:
            return "figure.walk.circle.fill"
        case .walkingChewing:
            return "figure.walk"
        case .walkingNonChewing:
            return "figure.walk.motion"
        }
    }
}

// MARK: - Uploading Overlay
private struct UploadingOverlay: View {
    var body: some View {
        ZStack {
            Color.black.opacity(0.5).ignoresSafeArea()
            VStack(spacing: 20) {
                ProgressView()
                    .scaleEffect(1.5)
                    .tint(.white)
                Text("正在上传数据...")
                    .font(.system(.body, design: .rounded).weight(.medium))
                    .foregroundColor(.white)
            }
            .padding(40)
            .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 20))
        }
    }
}

// MARK: - Components
private struct ScenarioCard: View {
    let scenario: Scenario
    
    var body: some View {
        ZStack {
            // 背景渐变 + 玻璃态效果
            RoundedRectangle(cornerRadius: 16, style: .continuous)
                .fill(
                    LinearGradient(
                        colors: scenario.gradient + [scenario.gradient.last!.opacity(0.7)],
                        startPoint: .topLeading,
                        endPoint: .bottomTrailing
                    )
                )
                .overlay(
                    RoundedRectangle(cornerRadius: 16, style: .continuous)
                        .fill(.white.opacity(0.1))
                        .blur(radius: 10)
                )
                .overlay(
                    RoundedRectangle(cornerRadius: 16, style: .continuous)
                        .strokeBorder(
                            LinearGradient(
                                colors: [.white.opacity(0.3), .white.opacity(0.1)],
                                startPoint: .topLeading,
                                endPoint: .bottomTrailing
                            ),
                            lineWidth: 1.5
                        )
                )
            
            // 装饰性圆形
            Circle()
                .fill(scenario.gradient.first!.opacity(0.2))
                .frame(width: 80, height: 80)
                .offset(x: 50, y: -30)
                .blur(radius: 20)
            
            Circle()
                .fill(scenario.gradient.last!.opacity(0.15))
                .frame(width: 60, height: 60)
                .offset(x: -40, y: 40)
                .blur(radius: 15)
            
            // 内容
            VStack(alignment: .leading, spacing: 10) {
                // 顶部：编号 + 图标
                HStack(spacing: 8) {
                    Text(scenario.code)
                        .font(.system(.caption, design: .rounded).weight(.black))
                        .foregroundStyle(
                            LinearGradient(
                                colors: [.white, .white.opacity(0.9)],
                                startPoint: .top,
                                endPoint: .bottom
                            )
                        )
                        .padding(.horizontal, 8)
                        .padding(.vertical, 4)
                        .background(
                            Capsule()
                                .fill(.white.opacity(0.25))
                                .shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1)
                        )
                    
                    Spacer()
                    
                    ZStack {
                        Circle()
                            .fill(.white.opacity(0.2))
                            .frame(width: 36, height: 36)
                        Image(systemName: scenario.icon)
                            .font(.system(size: 16, weight: .semibold))
                            .foregroundColor(.white)
                    }
                }
                
                // 标题
                Text(scenario.title)
                    .font(.system(.body, design: .rounded).weight(.bold))
                    .foregroundColor(.white)
                    .lineLimit(1)
                    .minimumScaleFactor(0.8)
                
                // 副标题
                Text(scenario.subtitle)
                    .font(.system(.caption, design: .rounded))
                    .foregroundColor(.white.opacity(0.85))
                    .lineLimit(1)
                    .minimumScaleFactor(0.9)
                
                Spacer()
                
                // 底部：时长
                HStack(spacing: 4) {
                    Image(systemName: "clock.fill")
                        .font(.system(size: 10, weight: .semibold))
                        .foregroundColor(.white.opacity(0.9))
                    Text(durationLabel)
                        .font(.system(.caption2, design: .rounded).weight(.medium))
                        .foregroundColor(.white.opacity(0.9))
                }
                .padding(.horizontal, 8)
                .padding(.vertical, 4)
                .background(
                    Capsule()
                        .fill(.black.opacity(0.2))
                )
            }
            .padding(14)
        }
        .frame(height: 140)
        .shadow(color: scenario.gradient.last!.opacity(0.4), radius: 12, x: 0, y: 8)
        .contentShape(Rectangle())
    }
    
    private var durationLabel: String {
        if scenario.hasRange {
            return "\(format(seconds: scenario.minDurationSec))-\(format(seconds: scenario.maxDurationSec))"
        } else {
            return format(seconds: scenario.minDurationSec)
        }
    }
    
    private func format(min: Double, max: Double) -> String {
        let a = format(seconds: min)
        let b = format(seconds: max)
        return "\(a) – \(b)"
    }
    private func format(seconds: Double) -> String {
        if seconds >= 60 {
            return String(format: "%.0f 分钟", seconds/60)
        } else {
            return String(format: "%.0f 秒", seconds)
        }
    }
}

private struct ScenarioConfirmSheet: View {
    let scenario: Scenario
    @Binding var duration: Double
    var onCancel: () -> Void
    var onConfirm: () -> Void
    
    var body: some View {
        VStack(spacing: 16) {
            Capsule().fill(.secondary.opacity(0.4)).frame(width: 40, height: 5).padding(.top, 8)
            HStack(spacing: 12) {
                Image(systemName: scenario.icon)
                    .font(.system(size: 22, weight: .semibold))
                    .foregroundStyle(LinearGradient(colors: scenario.gradient, startPoint: .topLeading, endPoint: .bottomTrailing))
                VStack(alignment: .leading) {
                    Text(scenario.title).font(.headline)
                    Text(scenario.subtitle).font(.subheadline).foregroundColor(.secondary)
                }
                Spacer()
            }
            
            VStack(alignment: .leading, spacing: 8) {
                Text("请根据提示准备：")
                    .font(.subheadline).fontWeight(.semibold)
                Text("• 请确保 AirPods 已连接并佩戴\n• 按提示开始后将倒计时 3,2,1\n• 期间尽量保持符合该场景的动作")
                    .font(.footnote)
                    .foregroundColor(.secondary)
            }
            .frame(maxWidth: .infinity, alignment: .leading)
            .padding()
            .background(.ultraThinMaterial, in: RoundedRectangle(cornerRadius: 16))
            
            if scenario.hasRange {
                VStack(alignment: .leading) {
                    HStack {
                        Text("选择时长")
                        Spacer()
                        Text(durationString)
                            .foregroundColor(.secondary)
                    }
                    Slider(value: $duration, in: scenario.minDurationSec...scenario.maxDurationSec, step: 10)
                }
            } else {
                HStack {
                    Text("时长")
                    Spacer()
                    Text(durationString)
                        .foregroundColor(.secondary)
                }
                .onAppear { duration = scenario.minDurationSec }
            }
            
            HStack(spacing: 12) {
                Button("取消", role: .cancel) { onCancel() }
                    .buttonStyle(.bordered)
                Button {
                    onConfirm()
                } label: {
                    Label("开始", systemImage: "play.fill")
                }
                .buttonStyle(.borderedProminent)
            }
            .padding(.top, 4)
            
            Spacer(minLength: 0)
        }
        .padding(20)
    }
    
    private var durationString: String {
        if duration >= 60 { return String(format: "%.0f 分钟", duration/60) }
        return String(format: "%.0f 秒", duration)
    }
}

private struct NoteInputSheet: View {
    @Binding var noteText: String
    var onSave: (String) -> Void
    
    var body: some View {
        VStack(spacing: 16) {
            Capsule().fill(.secondary.opacity(0.4)).frame(width: 40, height: 5).padding(.top, 8)
            Text("记录备注")
                .font(.headline)
            Text("请输入吃的东西（或填：没咀嚼）")
                .font(.footnote)
                .foregroundColor(.secondary)
            TextField("如：花生/苹果/没咀嚼", text: $noteText)
                .textFieldStyle(.roundedBorder)
            HStack(spacing: 12) {
                Button("跳过") { onSave("") }
                    .buttonStyle(.bordered)
                Button("保存") {
                    onSave(noteText)
                }
                .buttonStyle(.borderedProminent)
            }
            Spacer(minLength: 0)
        }
        .padding(20)
    }
}

// MARK: - Sensor Data Card
private struct SensorDataCard: View {
    let title: String
    let icon: String
    let color: Color
    let xValue: Double
    let yValue: Double
    let zValue: Double
    let unit: String
    
    var body: some View {
        VStack(spacing: 8) {
            HStack(spacing: 8) {
                Image(systemName: icon)
                    .font(.system(size: 16, weight: .semibold))
                    .foregroundColor(color)
                Text(title)
                    .font(.system(.subheadline, design: .rounded).weight(.semibold))
                    .foregroundColor(.white)
                Spacer()
            }
            
            HStack(spacing: 12) {
                SensorAxisView(axis: "X", value: xValue, unit: unit, color: .red)
                SensorAxisView(axis: "Y", value: yValue, unit: unit, color: .green)
                SensorAxisView(axis: "Z", value: zValue, unit: unit, color: .blue)
            }
        }
        .padding(12)
        .background(.white.opacity(0.1))
        .cornerRadius(12)
    }
}

private struct SensorAxisView: View {
    let axis: String
    let value: Double
    let unit: String
    let color: Color
    
    var body: some View {
        VStack(spacing: 4) {
            Text(axis)
                .font(.system(.caption2, design: .rounded).weight(.bold))
                .foregroundColor(color)
            Text(String(format: "%.3f", value))
                .font(.system(.caption, design: .monospaced).weight(.medium))
                .foregroundColor(.white)
            
            // 可视化指示器
            ZStack {
                RoundedRectangle(cornerRadius: 2)
                    .fill(.white.opacity(0.2))
                    .frame(width: 4, height: 40)
                
                VStack {
                    if value > 0 {
                        Spacer()
                    }
                    RoundedRectangle(cornerRadius: 2)
                        .fill(color)
                        .frame(width: 4, height: min(abs(value) * 20, 20))
                    if value < 0 {
                        Spacer()
                    }
                }
                .frame(height: 40)
            }
        }
        .frame(maxWidth: .infinity)
    }
}
